package com.mvc.app;

import com.container.app.MContainer;
import com.container.app.MContainerManager;
import com.container.app.proxy.ContainerProxyHandler;
import com.mvc.app.exceptions.InvalidServletConfiguration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Georgiana.Scarlat
 * Date: 8/27/12
 * Time: 11:49 AM
 */

public class ActionServlet extends HttpServlet {

    public static final String CONFIGURATION_INIT_PARAMETER = "configuration";
    public static final String HAS_PROXY_INIT_PARAMETER = "hasProxy";
    public static final String PROXY_INIT_PARAM = "proxy";

    protected MContainer container;

    protected ModelGenerator modelGenerator;
    protected ActionRequestGenerator actionRequestGenerator;
    protected Dispatcher dispatcher;
    protected ViewGenerator viewGenerator;


    @Override
    public void init() throws ServletException {

        super.init();

        initContainer();

        getDependenciesFromContainer();
    }




    @Override
    public void destroy() {

        super.destroy();
        container.closeContainer();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        Model model = modelGenerator.createModel(container, request);

        ActionRequest actionRequest = actionRequestGenerator.createActionRequest(container, request.getPathInfo());

        actionRequest.setRequestAndResponse(request, response);

        ModelView modelView = dispatcher.dispatchToController(actionRequest, model);

        viewGenerator.generateView(modelView, response);

    }

    private void getDependenciesFromContainer() {

        modelGenerator = container.getInstance(ModelGenerator.class);
        actionRequestGenerator = container.getInstance(ActionRequestGenerator.class);
        dispatcher = container.getInstance(Dispatcher.class);
        viewGenerator = container.getInstance(ViewGenerator.class);
    }

    private void initContainer() {
        String configFile = getInitParameter(CONFIGURATION_INIT_PARAMETER);
        Boolean hasProxy = Boolean.valueOf(getInitParameter(HAS_PROXY_INIT_PARAMETER));

        try {

            Class proxyHandlerClass = getProxyHandlerClass(hasProxy);

            checkValidProxyHandlerClass(proxyHandlerClass);

            //noinspection unchecked
            container = new MContainerManager(configFile, null, proxyHandlerClass);


        } catch (ClassNotFoundException e) {
            throw new InvalidServletConfiguration("Invalid init param 'proxy'.", e);
        }
    }

    private Class getProxyHandlerClass(Boolean hasProxy) throws ClassNotFoundException {

        if (hasProxy) {
            String proxyHandlerClassName = getInitParameter(PROXY_INIT_PARAM);
            return Class.forName(proxyHandlerClassName);
        }
        return null;
    }

    private void checkValidProxyHandlerClass(Class proxyHandlerClass) {
        if(proxyHandlerClass != null && !ContainerProxyHandler.class.isAssignableFrom(proxyHandlerClass))
            throw new InvalidServletConfiguration("Invalid init param 'proxy'.");
    }

}
